{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3504f1f4",
   "metadata": {},
   "source": [
    "## Week 4 Python to Golang code coverter\n",
    "# A race between open source models"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7a3faf77",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import gradio as gr\n",
    "import pandas as pd\n",
    "import traceback\n",
    "import time\n",
    "import subprocess\n",
    "import tempfile\n",
    "from huggingface_hub import InferenceClient\n",
    "from openai import OpenAI\n",
    "\n",
    "HF_TOKEN = os.getenv(\"HF_TOKEN\", \"\")\n",
    "OPENAI_KEY = os.getenv(\"OPENAI_API_KEY\", \"\")\n",
    "\n",
    "print(f\"HF Token: {'✓ Found' if HF_TOKEN else '✗ Not found'}\")\n",
    "print(f\"OpenAI Key: {'✓ Found' if OPENAI_KEY else '✗ Not found'}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "268e5500",
   "metadata": {},
   "outputs": [],
   "source": [
    "system_info = \"Mac M2, ARM64 architecture\"\n",
    "compile_command = \"go build -o main main.go && ./main\"\n",
    "\n",
    "system_prompt = \"\"\"Your task is to convert Python code into high performance Golang code. \n",
    "Respond only with golang code. Do not provide any explanation other than occasional comments. \n",
    "The Golang response needs to produce an identical output in the fastest possible time.\"\"\"\n",
    "\n",
    "def user_prompt_for(python):\n",
    "    return f\"\"\"Port this Python code to Golang with the fastest possible implementation that produces identical output in the least time.\n",
    "\n",
    "The system information is: {system_info}\n",
    "Your response will be written to a file called main.go and then compiled and executed.\n",
    "The compilation command is: {compile_command}\n",
    "\n",
    "Respond only with golang code.\n",
    "\n",
    "Python code to port:\n",
    "```python\n",
    "{python}\n",
    "```\n",
    "\"\"\"\n",
    "\n",
    "def messages_for(python):\n",
    "    return [\n",
    "        {\"role\": \"system\", \"content\": system_prompt},\n",
    "        {\"role\": \"user\", \"content\": user_prompt_for(python)}\n",
    "    ]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "27a100d4",
   "metadata": {},
   "outputs": [],
   "source": [
    "SAMPLE_CODES = {\n",
    "    \"Hello World\": \"print('Hello, World!')\",\n",
    "    \"Fibonacci\": \"\"\"def fibonacci(n):\n",
    "    if n <= 1:\n",
    "        return n\n",
    "    return fibonacci(n-1) + fibonacci(n-2)\n",
    "\n",
    "result = fibonacci(10)\n",
    "print(f'Fibonacci(10) = {result}')\"\"\",\n",
    "    \"Sum List\": \"\"\"numbers = [1, 2, 3, 4, 5]\n",
    "total = sum(numbers)\n",
    "print(f'Sum: {total}')\"\"\",\n",
    "    \"Pi Calculation\": \"\"\"import time\n",
    "\n",
    "def calculate(iterations, param1, param2):\n",
    "    result = 1.0\n",
    "    for i in range(1, iterations+1):\n",
    "        j = i * param1 - param2\n",
    "        result -= (1/j)\n",
    "        j = i * param1 + param2\n",
    "        result += (1/j)\n",
    "    return result\n",
    "\n",
    "start_time = time.time()\n",
    "result = calculate(200_000_000, 4, 1) * 4\n",
    "end_time = time.time()\n",
    "\n",
    "print(f\"Result: {result:.12f}\")\n",
    "print(f\"Execution Time: {(end_time - start_time):.6f} seconds\")\"\"\"\n",
    "}\n",
    "\n",
    "HF_MODELS = {\n",
    "    \"CodeLlama-7B\": \"codellama/CodeLlama-7b-Instruct-hf\",\n",
    "    \"StarCoder2-7B\": \"bigcode/starcoder2-7b\",\n",
    "    \"DeepSeek-Coder-6.7B\": \"deepseek-ai/deepseek-coder-6.7b-instruct\",\n",
    "    \"Phi-3-Mini\": \"microsoft/Phi-3-mini-4k-instruct\",\n",
    "    \"Mistral-7B\": \"mistralai/Mistral-7B-Instruct-v0.2\"\n",
    "}\n",
    "\n",
    "OPENAI_MODELS = {\n",
    "    \"GPT-4\": \"gpt-4\",\n",
    "    \"GPT-4-Turbo\": \"gpt-4-turbo-preview\",\n",
    "    \"GPT-3.5-Turbo\": \"gpt-3.5-turbo\"\n",
    "}\n",
    "\n",
    "ALL_MODELS = {**HF_MODELS, **OPENAI_MODELS}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34cff8b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "def run_python_code(python_code):\n",
    "    \"\"\"Run Python code and measure execution time\"\"\"\n",
    "    try:\n",
    "        with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:\n",
    "            f.write(python_code)\n",
    "            temp_file = f.name\n",
    "        \n",
    "        start_time = time.time()\n",
    "        result = subprocess.run(\n",
    "            ['python3', temp_file],\n",
    "            capture_output=True,\n",
    "            text=True,\n",
    "            timeout=30\n",
    "        )\n",
    "        end_time = time.time()\n",
    "        \n",
    "        os.unlink(temp_file)\n",
    "        \n",
    "        if result.returncode == 0:\n",
    "            return end_time - start_time, result.stdout, \"\"\n",
    "        else:\n",
    "            return 0, \"\", result.stderr\n",
    "            \n",
    "    except subprocess.TimeoutExpired:\n",
    "        return 0, \"\", \"Timeout (30s)\"\n",
    "    except Exception as e:\n",
    "        return 0, \"\", str(e)\n",
    "\n",
    "def run_golang_code(golang_code):\n",
    "    \"\"\"Compile and run Go code and measure execution time\"\"\"\n",
    "    try:\n",
    "        with tempfile.TemporaryDirectory() as temp_dir:\n",
    "            go_file = os.path.join(temp_dir, \"main.go\")\n",
    "            with open(go_file, 'w') as f:\n",
    "                f.write(golang_code)\n",
    "            \n",
    "            compile_result = subprocess.run(\n",
    "                ['go', 'build', '-o', 'main', 'main.go'],\n",
    "                cwd=temp_dir,\n",
    "                capture_output=True,\n",
    "                text=True,\n",
    "                timeout=30\n",
    "            )\n",
    "            \n",
    "            if compile_result.returncode != 0:\n",
    "                return 0, \"\", f\"Compile error: {compile_result.stderr}\"\n",
    "            \n",
    "            start_time = time.time()\n",
    "            run_result = subprocess.run(\n",
    "                ['./main'],\n",
    "                cwd=temp_dir,\n",
    "                capture_output=True,\n",
    "                text=True,\n",
    "                timeout=30\n",
    "            )\n",
    "            end_time = time.time()\n",
    "            \n",
    "            if run_result.returncode == 0:\n",
    "                return end_time - start_time, run_result.stdout, \"\"\n",
    "            else:\n",
    "                return 0, \"\", run_result.stderr\n",
    "                \n",
    "    except subprocess.TimeoutExpired:\n",
    "        return 0, \"\", \"Timeout (30s)\"\n",
    "    except Exception as e:\n",
    "        return 0, \"\", str(e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c0b2eb6c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def convert_with_openai(python_code, model_name, api_key):\n",
    "    try:\n",
    "        client = OpenAI(api_key=api_key)\n",
    "        messages = messages_for(python_code)\n",
    "        \n",
    "        response = client.chat.completions.create(\n",
    "            model=model_name,\n",
    "            messages=messages,\n",
    "            max_tokens=2000,\n",
    "            temperature=0.1\n",
    "        )\n",
    "        \n",
    "        golang_code = response.choices[0].message.content.strip()\n",
    "        return golang_code\n",
    "        \n",
    "    except Exception as e:\n",
    "        raise Exception(f\"OpenAI Error: {str(e)}\")\n",
    "\n",
    "def convert_with_huggingface(python_code, model_name, hf_token):\n",
    "    try:\n",
    "        client = InferenceClient(token=hf_token)\n",
    "        messages = messages_for(python_code)\n",
    "        \n",
    "        response = client.chat_completion(\n",
    "            model=model_name,\n",
    "            messages=messages,\n",
    "            max_tokens=2000,\n",
    "            temperature=0.1\n",
    "        )\n",
    "        \n",
    "        golang_code = response.choices[0].message.content.strip()\n",
    "        return golang_code\n",
    "        \n",
    "    except Exception as e:\n",
    "        raise Exception(f\"HuggingFace Error: {str(e)}\")\n",
    "\n",
    "def convert_python_to_golang(python_code, model_name):\n",
    "    try:\n",
    "        if not python_code or not python_code.strip():\n",
    "            return \"\", \"Error: No code\", \"Empty input\"\n",
    "        \n",
    "        is_openai = model_name in OPENAI_MODELS\n",
    "        model_id = ALL_MODELS.get(model_name)\n",
    "        \n",
    "        if not model_id:\n",
    "            return \"\", f\"Error: Model not found\", f\"Invalid: {model_name}\"\n",
    "        \n",
    "        if is_openai:\n",
    "            if not OPENAI_KEY:\n",
    "                return \"\", \"Error: No OpenAI key\", \"Missing OPENAI_KEY\"\n",
    "        else:\n",
    "            if not HF_TOKEN:\n",
    "                return \"\", \"Error: No HF token\", \"Missing HF_TOKEN\"\n",
    "        \n",
    "        max_retries = 2\n",
    "        for attempt in range(max_retries):\n",
    "            try:\n",
    "                if is_openai:\n",
    "                    golang_code = convert_with_openai(python_code, model_id, OPENAI_KEY)\n",
    "                else:\n",
    "                    golang_code = convert_with_huggingface(python_code, model_id, HF_TOKEN)\n",
    "                \n",
    "                if \"```go\" in golang_code:\n",
    "                    parts = golang_code.split(\"```go\")\n",
    "                    if len(parts) > 1:\n",
    "                        golang_code = parts[1].split(\"```\")[0].strip()\n",
    "                elif \"```golang\" in golang_code:\n",
    "                    parts = golang_code.split(\"```golang\")\n",
    "                    if len(parts) > 1:\n",
    "                        golang_code = parts[1].split(\"```\")[0].strip()\n",
    "                \n",
    "                if golang_code.startswith(\"```\"):\n",
    "                    golang_code = golang_code[3:].strip()\n",
    "                if golang_code.endswith(\"```\"):\n",
    "                    golang_code = golang_code[:-3].strip()\n",
    "                \n",
    "                if golang_code and len(golang_code) > 10:\n",
    "                    provider = \"OpenAI\" if is_openai else \"HuggingFace\"\n",
    "                    return golang_code, f\"✓ Converted with {model_name} ({provider})\", \"\"\n",
    "                else:\n",
    "                    return \"\", \"Error: Empty response\", \"No valid code generated\"\n",
    "                \n",
    "            except Exception as e:\n",
    "                error_msg = str(e)\n",
    "                \n",
    "                if \"503\" in error_msg or \"loading\" in error_msg.lower():\n",
    "                    return \"\", f\"Model loading. Wait 30s\", f\"503: Initializing\"\n",
    "                \n",
    "                elif \"404\" in error_msg:\n",
    "                    return \"\", f\"Error 404: '{model_name}' not accessible\", f\"Try another model\"\n",
    "                \n",
    "                elif \"429\" in error_msg:\n",
    "                    return \"\", \"Rate limit. Wait 1 min\", \"429: Too many requests\"\n",
    "                \n",
    "                elif \"401\" in error_msg or \"403\" in error_msg:\n",
    "                    return \"\", \"Invalid API key\", \"Check credentials\"\n",
    "                \n",
    "                else:\n",
    "                    if attempt < max_retries - 1:\n",
    "                        time.sleep(3)\n",
    "                        continue\n",
    "                    return \"\", f\"Error: {error_msg[:100]}\", traceback.format_exc()\n",
    "        \n",
    "        return \"\", \"All retries failed\", \"Max attempts exceeded\"\n",
    "        \n",
    "    except Exception as e:\n",
    "        return \"\", f\"Error: {str(e)[:100]}\", traceback.format_exc()\n",
    "\n",
    "def write_output(go_code):\n",
    "    try:\n",
    "        with open(\"main.go\", \"w\", encoding=\"utf-8\") as f:\n",
    "            f.write(go_code)\n",
    "        return \"✓ Written to main.go\"\n",
    "    except Exception as e:\n",
    "        return f\"Error writing file: {str(e)}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "91f01137",
   "metadata": {},
   "outputs": [],
   "source": [
    "custom_css = \"\"\"\n",
    ".gradio-container {\n",
    "    font-family: 'Inter', sans-serif;\n",
    "}\n",
    ".main-header {\n",
    "    text-align: center;\n",
    "    padding: 2rem 0;\n",
    "    background: linear-gradient(135deg, #2193b0 0%, #6dd5ed 100%);\n",
    "    color: white;\n",
    "    border-radius: 8px;\n",
    "    margin-bottom: 2rem;\n",
    "}\n",
    "\"\"\"\n",
    "\n",
    "demo = gr.Blocks(css=custom_css, title=\"Python to Golang Converter\", theme=gr.themes.Soft())\n",
    "\n",
    "with demo:\n",
    "    gr.HTML(\"\"\"\n",
    "    <div class=\"main-header\">\n",
    "        <h1>Python to Golang Code Converter</h1>\n",
    "        <p>High-performance code conversion with runtime comparison</p>\n",
    "    </div>\n",
    "    \"\"\")\n",
    "    \n",
    "    hf_status = \"✓ Configured\" if HF_TOKEN else \"✗ Not Found\"\n",
    "    hf_color = \"green\" if HF_TOKEN else \"red\"\n",
    "    \n",
    "    openai_status = \"✓ Configured\" if OPENAI_KEY else \"✗ Not Found\"\n",
    "    openai_color = \"green\" if OPENAI_KEY else \"red\"\n",
    "    \n",
    "    gr.HTML(f\"\"\"\n",
    "    <div style=\"padding: 1rem; background-color: #f8f9fa; border-radius: 8px; margin-bottom: 1rem;\">\n",
    "        <p style=\"margin: 0; color: {hf_color};\"><strong>HF Token:</strong> {hf_status}</p>\n",
    "        <p style=\"margin: 0.5rem 0 0 0; color: {openai_color};\"><strong>OpenAI Key:</strong> {openai_status}</p>\n",
    "        \n",
    "    </div>\n",
    "    \"\"\")\n",
    "    \n",
    "    with gr.Tabs():\n",
    "        with gr.Tab(\"Convert Code\"):\n",
    "            with gr.Row():\n",
    "                with gr.Column():\n",
    "                    sample_selector = gr.Dropdown(\n",
    "                        choices=list(SAMPLE_CODES.keys()),\n",
    "                        label=\"Load Sample\",\n",
    "                        value=\"Hello World\"\n",
    "                    )\n",
    "                    \n",
    "                    python_editor = gr.Code(\n",
    "                        label=\"Python Code\",\n",
    "                        value=SAMPLE_CODES[\"Hello World\"],\n",
    "                        language=\"python\",\n",
    "                        lines=15,\n",
    "                        interactive=True\n",
    "                    )\n",
    "                    \n",
    "                    model_selector = gr.Radio(\n",
    "                        choices=list(ALL_MODELS.keys()),\n",
    "                        label=\"Select Model\",\n",
    "                        value=\"GPT-4\" if OPENAI_KEY else \"CodeLlama-7B\"\n",
    "                    )\n",
    "                    \n",
    "                    with gr.Row():\n",
    "                        convert_btn = gr.Button(\"Convert to Golang\", variant=\"primary\")\n",
    "                        save_btn = gr.Button(\"Save to main.go\", variant=\"secondary\")\n",
    "                \n",
    "                with gr.Column():\n",
    "                    golang_editor = gr.Textbox(\n",
    "                        label=\"Generated Golang Code\",\n",
    "                        lines=15,\n",
    "                        interactive=True,\n",
    "                        show_copy_button=True\n",
    "                    )\n",
    "                    \n",
    "                    save_status = gr.Textbox(\n",
    "                        label=\"Save Status\",\n",
    "                        lines=1,\n",
    "                        interactive=False\n",
    "                    )\n",
    "            \n",
    "            with gr.Row():\n",
    "                conversion_status = gr.Textbox(\n",
    "                    label=\"Status\",\n",
    "                    lines=2,\n",
    "                    interactive=False\n",
    "                )\n",
    "            \n",
    "            with gr.Row():\n",
    "                error_display = gr.Textbox(\n",
    "                    label=\"Error Details\",\n",
    "                    lines=8,\n",
    "                    interactive=False,\n",
    "                    visible=True,\n",
    "                    show_copy_button=True\n",
    "                )\n",
    "            \n",
    "            sample_selector.change(\n",
    "                fn=lambda x: load_sample(x),\n",
    "                inputs=[sample_selector],\n",
    "                outputs=[python_editor, error_display]\n",
    "            )\n",
    "            \n",
    "            def convert_only(python_code, model_name):\n",
    "                try:\n",
    "                    if not python_code:\n",
    "                        return \"\", \"Error: No code\", \"Empty\"\n",
    "                    return convert_python_to_golang(python_code, model_name)\n",
    "                except Exception as e:\n",
    "                    return \"\", f\"Error: {str(e)}\", traceback.format_exc()\n",
    "            \n",
    "            convert_btn.click(\n",
    "                fn=convert_only,\n",
    "                inputs=[python_editor, model_selector],\n",
    "                outputs=[golang_editor, conversion_status, error_display]\n",
    "            )\n",
    "            \n",
    "            save_btn.click(\n",
    "                fn=write_output,\n",
    "                inputs=[golang_editor],\n",
    "                outputs=[save_status]\n",
    "            )\n",
    "        \n",
    "        with gr.Tab(\"Compare Models & Runtime\"):\n",
    "            gr.Markdown(\"### Compare All Models with Runtime Performance\")\n",
    "            \n",
    "            with gr.Row():\n",
    "                with gr.Column():\n",
    "                    sample_selector2 = gr.Dropdown(\n",
    "                        choices=list(SAMPLE_CODES.keys()),\n",
    "                        label=\"Load Sample\",\n",
    "                        value=\"Pi Calculation\"\n",
    "                    )\n",
    "                    \n",
    "                    python_input2 = gr.Code(\n",
    "                        label=\"Python Code\",\n",
    "                        value=SAMPLE_CODES[\"Pi Calculation\"],\n",
    "                        language=\"python\",\n",
    "                        lines=12,\n",
    "                        interactive=True\n",
    "                    )\n",
    "                    \n",
    "                    compare_btn = gr.Button(\"Compare All Models\", variant=\"primary\", size=\"lg\")\n",
    "            \n",
    "            with gr.Row():\n",
    "                comparison_summary = gr.Textbox(\n",
    "                    label=\"Summary\",\n",
    "                    interactive=False,\n",
    "                    lines=2\n",
    "                )\n",
    "            \n",
    "            with gr.Row():\n",
    "                comparison_table = gr.Dataframe(\n",
    "                    label=\"Runtime Comparison Results\",\n",
    "                    interactive=False,\n",
    "                    wrap=True\n",
    "                )\n",
    "            \n",
    "            with gr.Row():\n",
    "                compare_error = gr.Textbox(\n",
    "                    label=\"Error Details\",\n",
    "                    lines=8,\n",
    "                    interactive=False,\n",
    "                    visible=True,\n",
    "                    show_copy_button=True\n",
    "                )\n",
    "            \n",
    "            sample_selector2.change(\n",
    "                fn=lambda x: load_sample(x),\n",
    "                inputs=[sample_selector2],\n",
    "                outputs=[python_input2, compare_error]\n",
    "            )\n",
    "            \n",
    "            compare_btn.click(\n",
    "                fn=compare_all_models,\n",
    "                inputs=[python_input2],\n",
    "                outputs=[comparison_table, comparison_summary, compare_error]\n",
    "            )\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "89abbebf",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "#Launch\n",
    "demo.launch()\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
